<template>
  <div class="app-container">
    <!-- 查询 -->
    <div class="filter-container">
      <el-row :gutter="0">
        <el-form :inline="true" class="search-form">
          <el-form-item label="">
            <el-input v-model="query.name" placeholder="请输入名称" class="input-with-select">
              <el-select v-model="query.keyword_type" slot="prepend" class="" placeholder="请选择">
                <el-option value="name" label="名称" />
              </el-select>
            </el-input>
          </el-form-item>
          <el-form-item label="类型">
            <el-select v-model="query.type" class="filter-item" placeholder="" style="width:110px;" clearable>
              <el-option value="1" label="类型1" />
              <el-option value="2" label="类型2" />
              <el-option value="3" label="类型3" />
            </el-select>
          </el-form-item>
          <el-form-item label="" style="width:110px;margin-right: 0">
            <el-select v-model="query.time_type" class="" placeholder="时间类型">
              <el-option value="created_at" label="添加时间" />
              <el-option value="updated_at" label="修改时间" />
            </el-select>
          </el-form-item>
          <el-form-item label="">
            <el-date-picker
              v-model="query.date_value"
              type="daterange"
              class="filter-item"
              range-separator="-"
              value-format="yyyy-MM-dd"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              style="width: 240px"
            />
          </el-form-item>
          <el-form-item>
            <el-button class="" type="primary" icon="el-icon-search" circle @click="search"></el-button>
            <el-button class="" type="success" icon="el-icon-refresh-right" circle plain @click="refresh()"></el-button>
            <el-button class="" type="warning" icon="el-icon-download" @click="doExport()">导出</el-button>
          </el-form-item>

          <el-form-item style="float: right">
            <el-button class="" type="primary" @click="add()">添加</el-button>
          </el-form-item>
        </el-form>
      </el-row>

      <el-row :gutter="0">
        <el-col :xs="24" :sm="16">
          <div class="left-panel">
            <el-checkbox v-model="isSelectAll" class="filter-item" border style="margin-right: 10px" @change="selectAll()">全选</el-checkbox>
            <el-button class="filter-item" type="warning" @click="batchSelect('hide')">批量操作</el-button>
            <el-button class="filter-item" type="danger" icon="el-icon-delete" @click="batchDel(selection)">批量删除</el-button>
          </div>
        </el-col>
        <el-col :xs="24" :sm="8">
          <div class="right-panel el-button-group">
            <el-button class="" icon="el-icon-refresh" @click="refresh"></el-button>
            <el-dropdown trigger="click" :hide-on-click="false" @command="handleTableTheadCommand">
              <span class="el-dropdown-link">
                <el-button class="" icon="el-icon-s-operation"></el-button>
              </span>
              <el-dropdown-menu slot="dropdown">
                <el-dropdown-item v-for="fruit in allTableThead" :key="fruit" :command="fruit">
                  <el-checkbox v-model="checkboxTableThead" :label="fruit">{{ tableTheadOptions[fruit].label }}</el-checkbox>
                </el-dropdown-item>
              </el-dropdown-menu>
            </el-dropdown>
          </div>
        </el-col>
      </el-row>
    </div>
    <!-- 列表 -->
    <el-table ref="tableRef" v-loading="loading" :data="datas" :default-sort="{prop: 'id', order: 'descending'}" style="width: 100%" border stripe @sort-change="sorting" row-key="id" @selection-change="select">
      <el-table-column type="selection" min-width="40" align="center"/>
      <el-table-column prop="id" label="ID" align="center" sortable="custom"/>
      <el-table-column prop="name" label="名称" min-width="120" align="center" show-overflow-tooltip>
        <template slot-scope="scope">
          {{ scope.row.name }}
        </template>
      </el-table-column>
      <!--<el-table-column prop="created_at" label="创建时间" min-width="160" align="center" sortable="custom"/>
      <el-table-column prop="sorting" label="排序" width="75" align="center" sortable="custom"/>-->
      <el-table-column v-for="fruit in tableThead" :key="fruit" :label="tableTheadOptions[fruit].label" align="center">
        <template slot-scope="scope">
          {{ scope.row[fruit] }}
        </template>
      </el-table-column>
      <el-table-column label="操作" min-width="160" align="center" fixed="right">
        <!--<template slot-scope="{ row }">
          <el-button type="primary" size="mini" @click="edit(row)">编辑</el-button>
          <el-button type="danger" size="small" @click="del(row)">删除</el-button>
        </template>-->
        <template slot-scope="scope">
          <el-button type="primary" icon="el-icon-edit" size="mini" @click="edit(scope)">编辑</el-button>
          <el-button type="danger" icon="el-icon-delete" size="mini" @click="del([scope.row])">删除</el-button>
          <router-link :to="'/admin/test/edit/'+scope.row.id" style="margin-left: 10px">
            <el-button type="info" size="mini">新窗口编辑</el-button>
          </router-link>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页 -->
    <pagination v-show="total > 0" :total="total" :page.sync="query.page" :limit.sync="query.limit" @pagination="list"/>

    <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" top="15vh" :close-on-click-modal="false" :before-close="cancel" @opened="dialogOpened()" @closed="dialogClosed()">
      <el-form ref="ref" :model="model" :rules="rules" class="dialog-body" label-width="100px">
        <el-form-item label="名称" prop="name">
          <el-input v-model="model.name" placeholder="请输入名称" clearable/>
        </el-form-item>
        <el-form-item label="详细" prop="info">
          <el-input v-model="model.info" type="textarea" maxlength="40" placeholder="" show-word-limit/>
        </el-form-item>
        <el-form-item label="排序" prop="sort">
          <el-input-number v-model="model.sorting" :min="1" :max="99999" step-strictly/>
        </el-form-item>
        <el-form-item label="用户">
          <el-input v-model="model.user_name" :disabled="true">
            <template slot="append">
              <el-button @click="userDialog = true">选择用户</el-button>
            </template>
          </el-input>
        </el-form-item>
        <el-form-item label="地址" prop="district">
          <el-cascader
            ref="regionRef"
            v-model="model.district"
            :options="regionTree"
            :props="{children: 'children', value: 'name', label: 'name'}"
            clearable
            filterable
            @change="pickRegion"
            style="width: 100%"
          >
            <template slot-scope="{ node, data }">
              <span>{{ data.name }}</span>
              <span v-if="!node.isLeaf"> ({{ data.children.length }})</span>
            </template>
          </el-cascader>
        </el-form-item>
        <el-form-item label="" prop="latitude">
          <el-input v-model="model.details" id="mapKeyword" placeholder="请输入请输入详细地址" suffix-icon="el-icon-location" clearable/>
          <baidu-map keyword-id="mapKeyword" :address-detail="{longitude: model.longitude, latitude: model.latitude}" @mapCallback="mapCallback"/>
        </el-form-item>
        <el-form-item label="表单内容">
          <el-table class="content-table" ref="contentRef" :data="model.form_content" row-key="id" style="width: 100%" border>
            <el-table-column label="字段名" min-width="120" align="center">
              <template slot-scope="scope">
                <el-form-item
                  :prop="'form_content.' + scope.$index + '.name'"
                  :rules="{
                    required: true, message: '请输入字段名', trigger: 'blur'
                  }"
                >
                  <el-input v-model="scope.row.name" type="text" maxlength="40" placeholder="40个字符内"/>
                </el-form-item>
              </template>
            </el-table-column>
            <el-table-column label="类型" min-width="120" align="center">
              <template slot-scope="scope">
                <el-form-item
                  :prop="'form_content.' + scope.$index + '.type'"
                  :rules="{
                    required: true, message: '请选择类型', trigger: 'blur'
                  }"
                >
                  <el-select v-model="scope.row.type" placeholder="请选择" clearable>
                    <el-option v-for="(fieldType, fieldTypeKey) in formContent.fieldTypes" :key="fieldTypeKey" :value="fieldTypeKey | stringToNumber" :label="fieldType"></el-option>
                  </el-select>
                </el-form-item>
              </template>
            </el-table-column>
            <el-table-column label="配置" min-width="120" align="center">
              <template slot-scope="scope">
                <el-form-item
                  :prop="'form_content.' + scope.$index + '.input_type'"
                  :rules="{
                    required: true, message: '请选择配置', trigger: 'blur'
                  }"
                >
                  <el-select v-model="scope.row.input_type" placeholder="请选择">
                    <el-option v-for="(inputType, inputTypeKey) in formContent.inputTypes" :key="inputTypeKey" :value="inputTypeKey | stringToNumber" :label="inputType"></el-option>
                  </el-select>
                </el-form-item>
              </template>
            </el-table-column>
            <el-table-column label="选项值" min-width="120" align="center">
              <template slot-scope="scope">
                <el-form-item
                  v-if="[2, 3].includes(scope.row.type)"
                  :prop="'form_content.' + scope.$index + '.option'"
                  :rules="{
                    required: true, message: '请选择类型', trigger: 'blur'
                  }"
                >
                  <el-input v-model="scope.row.option" type="textarea" maxlength="200" placeholder="多个值以英文逗号分隔"/>
                </el-form-item>
              </template>
            </el-table-column>
            <el-table-column label="操作" min-width="80" align="center">
              <template slot-scope="{ row }">
                <el-button type="danger" icon="el-icon-close" size="mini" @click="delContent(row)"></el-button>
                <el-tooltip class="item" effect="dark" content="拖拽排序" placement="left">
                  <el-button class="sortable-btn" type="success" icon="el-icon-rank" size="mini" ></el-button>
                </el-tooltip>
              </template>
            </el-table-column>
          </el-table>
          <el-button type="info" icon="el-icon-circle-plus-outline" size="mini" @click="addContent()">新增内容项</el-button>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button :loading="btnLoading" type="primary" @click="submit">确 定</el-button>
      </div>
    </el-dialog>

    <el-dialog title="用户" :visible.sync="userDialog" width="70%" top="10vh" append-to-body>
      <radio-user @radioCallback="userCallback"/>
    </el-dialog>
  </div>
</template>

<script>
import {mapGetters} from 'vuex'
import Sortable from 'sortablejs'
import screenHeight from '@/utils/screen-height'
import Pagination from '@/components/Pagination'
import RadioUser from '../components/RadioUser'
import BaiduMap from '@/components/Map/baidu'
import {getRegion} from '@/api/admin/common'
import {list, info, save, del, doExport} from '@/api/admin/test'

const tableTheadOption = {
  created_at :{
    label: '创建时间',
    field: 'created_at',
  },
  updated_at :{
    label: '更新时间',
    field: 'updated_at',
  },
  sorting :{
    label: '排序',
    field: 'sorting',
  }
}

const allTableThead = ['created_at', 'updated_at', 'sorting']
const defaultTableThead = ['created_at', 'sorting']

export default {
  name: 'AdminTest',
  components: {Pagination, RadioUser, BaiduMap},
  data() {
    return {
      name: '大数据测试',
      height: 680,
      loading: false,
      datas: [],
      total: 0,
      query: {
        page: 1,
        limit: 20,
        keyword_type: 'name',
        type: '1', // 不能用数字
        time_type: 'created_at',
        date_value: ''
      },
      dialogVisible: false,
      dialogTitle: '',
      btnLoading: false,
      model: {
        id: '',
        created_at: '',
        updated_at: '',
        name: '',
        info: '',
        sorting: 100,
        status: 1,

        user_id: '',
        user_name: '',

        province: '',
        province_id: '',
        city: '',
        city_id: '',
        district: '',
        district_id: '',
        details: '',
        latitude: '',
        longitude: '',

        form_content: [],
      },
      rules: {
        name: [{required: true, message: '请输入名称', trigger: 'blur'}]
      },

      selection: [], // 选中项
      isSelectAll: false,

      tableKey: 1, // table key
      tableTheadOptions: tableTheadOption,
      allTableThead: allTableThead,
      tableThead: defaultTableThead, // 默认表头
      checkboxTableThead: defaultTableThead, // 默认表头值

      userDialog: false,
      regionTree: [],
      formContent: {
        fieldTypes: {
          1: '单行文本',
          2: '单选',
          3: '多选',
          4: '省市区',
          5: '地图定位',
          6: '时间选择',
          7: '姓名+性别',
          8: '手机号',
        },
        inputTypes: {
          0: '不限',
          1: '数字'
        }
      }
    }
  },
  computed: {
    ...mapGetters(['adminInfo'])
  },
  watch: {
    checkboxTableThead(valArr) {
      this.tableThead = this.allTableThead.filter(i => valArr.indexOf(i) >= 0)
      this.tableKey = this.tableKey + 1 // 为了保证table 每次都会重渲
    },
    'model.form_content': function (val, oldval) {
      if (!this.sortable && this.dialogVisible && val.length > 0) {
        this.setSort()
      }
    }
  },
  created() {
    this.height = screenHeight()
    this.list()
    console.log(this.adminInfo)
  },
  methods: {
    // 列表
    list() {
      this.loading = true
      list(this.query).then(res => {
        this.datas = res.data.data
        this.total = res.data.total
        this.loading = false
      }).catch(() => {
        this.loading = false
      })
    },
    // 添加
    add() {
      this.dialogVisible = true
      this.dialogTitle = '新增'
      this.getRegions()
      this.reset()
    },
    // 修改
    edit({$index, row}) {
      this.dialogVisible = true
      this.dialogTitle = '编辑：' + row.id
      this.getRegions()
      this.reset()
      info({
        id: row.id
      }).then(res => {
        this.model = res.data
      })
    },
    // 删除
    del(row) {
      if (!row.length) {
        this.selectMsg()
      } else {
        var title = '删除' + this.name
        var message = '确定要删除选中的 <span style="color:red">' + row.length + ' </span> 条' + this.name + '数据吗？'
        if (row.length === 1) {
          title = title + 'ID：' + row[0].id
          message = '确定要删除' + this.name + ' <span style="color:red">' + row[0].name + ' </span> 这条数据吗？'
        }
        this.$confirm(message, title, {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
          dangerouslyUseHTMLString: true // 解析html标签
        }).then(() => {
          this.loading = true
          del({
            data: row
          }).then(res => {
            this.list()
            this.$message.success(res.msg)
          }).catch(() => {
            this.loading = false
          })
        }).catch(() => {
        })
      }
    },
    // 取消
    cancel() {
      this.reset()
      this.dialogVisible = false
    },
    // 提交
    submit() {
      this.$refs['ref'].validate(valid => {
        if (valid) {
          this.btnLoading = true
          save(this.model, 'post').then(res => {
            this.btnLoading = false
            this.list()
            this.dialogVisible = false
            this.$message.success(res.msg)
          }).catch(() => {
            this.btnLoading = false
          })
        }
      })
    },
    // 重置
    reset() {
      this.model = this.$options.data().model
      if (this.$refs['ref'] !== undefined) {
        this.$refs['ref'].resetFields()
      }
    },
    // 查询
    search() {
      this.query.page = 1
      this.list()
    },
    // 刷新
    refresh() {
      this.query = this.$options.data().query
      this.list()
    },
    // 排序
    sorting(sort) {
      this.query.sort_field = sort.prop
      this.query.sort_value = ''
      if (sort.order === 'ascending') {
        this.query.sort_value = 'asc'
        this.list()
      }
      if (sort.order === 'descending') {
        this.query.sort_value = 'desc'
        this.list()
      }
    },

    // 全选操作 -- table 表头
    select(selection) {
      this.selection = selection
    },
    // 全选操作 -- 自定义按钮
    selectAll() {
      if (this.isSelectAll) {
        this.$refs.tableRef.toggleAllSelection()
      } else {
        this.$refs.tableRef.clearSelection()
      }
    },
    selectMsg(message = '') {
      this.$alert(message || '请选择需要操作的' + this.name, '提示', {
        confirmButtonText: '确定', callback: action => {
        }
      })
    },
    // 批量选择
    batchSelect(selectType) {
      if (!this.selection.length) {
        this.selectMsg()
      } else {
        console.log(selectType)
      }
    },
    // 批量删除
    batchDel(row) {
      this.del(row)
    },

    // 导出
    doExport(row) {
      const loading = this.$loading({
        lock: true,
        text: '数据下载中，请稍候...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      });
      doExport(this.query, 'post').then(res => {
        loading.close()
        //const blob = new Blob([data], {type: 'application/octet-stream'}) // 转换成二进制对象
        //const url = window.URL.createObjectURL(blob) // 二进制对象转换成url地址
        const url = res.data.url
        const link = document.createElement('a')
        link.setAttribute('download', '')
        link.style.display = 'none'
        link.href = url
        // 对下载的文件命名
        //link.download = ''
        document.body.appendChild(link)
        link.click()
        //link.remove()
        document.body.removeChild(link) // 下载完成移除元素
        window.URL.revokeObjectURL(url) // 释放掉blob对象
      }).catch(() => {
        loading.close()
      })
    },

    // table表头字段选择
    handleTableTheadCommand(command) {
      //this.$message('click on item ' + command);
    },

    // 打开dialog
    dialogOpened() {
      this.$notify({
        title: 'Success',
        dangerouslyUseHTMLString: true,
        message:
          `
            <div>打开dialog</div>
          `,
        type: 'success' // 可选info/warning/danger/success/primary
      })
    },
    dialogClosed() {
      /*this.$notify({
        title: 'Notice',
        dangerouslyUseHTMLString: true,
        message: `
            <div>关闭dialog</div>
          `,
        type: 'info'
      })*/
      //this.$message.info('关闭dialog')
      this.$message({
        showClose: true,
        message: this.$createElement('p', null, [
          this.$createElement('span', null, '关闭 '),
          this.$createElement('i', {style: 'color: teal'}, 'Dialog')
        ]),
        type: 'warning',
        duration: 0 // 显示时间, 毫秒。设为 0 则不会自动关闭
      })
    },

    // 选择用户回调
    userCallback(selected) {
      this.userDialog = false
      this.model.user_id = selected.id
      this.model.user_name = selected.name
    },

    // 地区
    getRegions() {
      if (this.regionTree.length < 1) {
        getRegion().then(res => {
          this.regionTree = res.data
        })
      }
    },
    // 地区选择
    pickRegion(value) {
      //console.log(value)
      let node = this.$refs['regionRef'].getCheckedNodes()
      let pathLabels = node[0].pathLabels
      this.model.province = pathLabels[0]
      this.model.city = pathLabels[1]
      this.model.district = pathLabels[2]
    },
    // 地图回调
    mapCallback(addressDetail) {
      this.model.longitude = addressDetail.longitude
      this.model.latitude = addressDetail.latitude
    },

    // 内容项
    addContent() {
      this.model.form_content.push({
        id: this.model.form_content.length,
        name: '',
        field: '',
        input_type: '',
        option: '',
      })
    },
    delContent(row) {
      var index = this.model.form_content.indexOf(row)
      if (index !== -1) {
        this.model.form_content.splice(index, 1)
      }
    },
    // 拖拽排序
    setSort() {
      const _this = this
      // 表格中需要实现行拖动，所以选中tr的父级元素
      //const el = document.querySelector('.content-table .el-table__body-wrapper tbody')
      //const el = this.$refs.contentRef.$el.querySelectorAll('.content-table > .el-table__body-wrapper > table > tbody')[0]
      const el = this.$refs.contentRef.$el.querySelector('.content-table .el-table__body-wrapper tbody')
      this.sortable = Sortable.create(el, {
        ghostClass: 'sortable-ghost', // Class name for the drop placeholder,
        setData: function (dataTransfer) {
          // to avoid Firefox bug (Detail see : https://github.com/RubaXa/Sortable/issues/1012)
          dataTransfer.setData('Text', '')
        },
        onEnd: evt => {
          const oldIndex = evt.oldIndex
          const newIndex = evt.newIndex
          const targetRow = this.model.form_content.splice(oldIndex, 1)[0]
          this.model.form_content.splice(newIndex, 0, targetRow)
        }
      })
    }
  }
}
</script>

<style>
.input-with-select .el-select .el-input {
  width: 130px;
}
.input-with-select .el-input-group__prepend {
  background-color: #fff;
}
</style>

<style scoped>
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}
</style>
